home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 June (DVD) / DPPRO0605DVD.iso / Install / program files / Borland / BDS / 3.0 / Demos / Delphi.Net / VCL / Lexer / mwStringStream.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2004-10-22  |  5.8 KB  |  237 lines

  1. unit mwStringStream;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, Classes;
  7.  
  8. procedure MoveNoOverlap(const Source; var Dest; count : Integer );
  9.  
  10. type
  11.   TmwStringStream = class(TStream)
  12.   private
  13.     FDataString: string;
  14.     FPosition: Integer;
  15.     FSize: Integer;
  16.     function GetDataString: string;
  17.     procedure Grow(Value: Integer);
  18.     procedure SetCapacity(const NewCapacity: Integer);
  19.     function GetCapacity: Integer;
  20.     procedure SetDataString(const Value: string);
  21.     function GetAsPChar: PChar;
  22.   protected
  23.     procedure SetSize(NewSize: Longint); override;
  24.   public
  25.     constructor Create; overload;
  26.     constructor Create(const AString: string); overload;
  27.     procedure Clear;
  28.     procedure LoadFromStream(Stream: TStream);
  29.     procedure LoadFromFile(const FileName: string);
  30.     function Read(var Buffer; Count: Longint): Longint; override;
  31.     function ReadString(Count: Longint): string;
  32.     function ReadWideString(Count: Longint): WideString;
  33.     procedure SaveToStream(Stream: TStream);
  34.     procedure SaveToFile(const FileName: string);
  35.     function Seek(Offset: Longint; Origin: Word): Longint; override;
  36.     function Write(const Buffer; Count: Longint): Longint; override;
  37.     procedure WriteString(const AString: string);
  38.     procedure WriteWideString(const AWideString: WideString);
  39.     property AsPChar: PChar read GetAsPChar;
  40.     property Capacity: Integer read GetCapacity write SetCapacity;
  41.     property DataString: string read GetDataString write SetDataString;
  42.   end;
  43.  
  44. implementation
  45.  
  46. procedure MoveNoOverlap(const Source; var Dest; count : Integer );
  47. asm
  48.         PUSH    ESI
  49.         PUSH    EDI
  50.  
  51.         MOV     ESI,EAX
  52.         MOV     EDI,EDX
  53.  
  54.         MOV     EAX,ECX
  55.  
  56.         SAR     ECX,2
  57.  
  58.         REP     MOVSD
  59.  
  60.         MOV     ECX,EAX
  61.         AND     ECX,03H
  62.         REP     MOVSB
  63.  
  64.         POP     EDI
  65.         POP     ESI
  66. end;
  67.  
  68. { TmwStringStream }
  69.  
  70. procedure TmwStringStream.Clear;
  71. begin
  72.   FDataString:= '';
  73.   FPosition:= 1;
  74.   FSize:= 0;
  75. end;
  76.  
  77. constructor TmwStringStream.Create;
  78. begin
  79.   inherited Create;
  80.   FPosition:= 1;
  81. end;
  82.  
  83. constructor TmwStringStream.Create(const AString: string);
  84. begin
  85.   inherited Create;
  86.   FDataString:= AString;
  87.   FSize:= Length(FDataString);
  88.   FPosition:= 1;
  89. end;
  90.  
  91. function TmwStringStream.GetAsPChar: PChar;
  92. begin
  93.   Result:= PChar(GetDataString);
  94. end;
  95.  
  96. function TmwStringStream.GetCapacity: Integer;
  97. begin
  98.   Result:= Length(FDataString);
  99. end;
  100.  
  101. function TmwStringStream.GetDataString: string;
  102. begin
  103.   if FSize <> Capacity then SetLength(FDataString, FSize);
  104.   Result:= FDataString;
  105. end;
  106.  
  107. procedure TmwStringStream.Grow(Value: Integer);
  108. var
  109.   Delta: Integer;
  110. begin
  111.   Delta := Capacity div 10;
  112.   SetCapacity(Capacity + Value + Delta);
  113. end;
  114.  
  115. procedure TmwStringStream.LoadFromFile(const FileName: string);
  116. var
  117.   Stream: TStream;
  118. begin
  119.   Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  120.   try
  121.     LoadFromStream(Stream);
  122.   finally
  123.     Stream.Free;
  124.   end;
  125. end;
  126.  
  127. procedure TmwStringStream.LoadFromStream(Stream: TStream);
  128. var
  129.   Count: Longint;
  130. begin
  131.   Stream.Position := 0;
  132.   Count := Stream.Size;
  133.   SetSize(Count);
  134.   if Count <> 0 then Stream.ReadBuffer(Pointer(FDataString)^, Count);
  135. end;
  136.  
  137. function TmwStringStream.Read(var Buffer; Count: Integer): Longint;
  138. begin
  139.   Result := FSize - FPosition;
  140.   if Result > Count then Result := Count;
  141.   MoveNoOverlap(Pointer(Integer(FDataString) + FPosition - 1)^, Buffer, Result);
  142.   Inc(FPosition, Result);
  143. end;
  144.  
  145. function TmwStringStream.ReadString(Count: Integer): string;
  146. var
  147.   Readed: Integer;
  148. begin
  149.   SetLength(Result, Count);
  150.   Readed := Read(Pointer(Result)^, Count);
  151.   if Readed <> Count then SetLength(Result, Readed);
  152. end;
  153.  
  154. function TmwStringStream.ReadWideString(Count: Integer): WideString;
  155. var
  156.   Readed: Integer;
  157. begin
  158.   SetLength(Result, Count);
  159.   Readed := Read(Pointer(Result)^, Count*2);
  160.   if Readed <> Count*2 then SetLength(Result, Readed div 2);
  161. end;
  162.  
  163. procedure TmwStringStream.SaveToFile(const FileName: string);
  164. var
  165.   Stream: TStream;
  166. begin
  167.   Stream := TFileStream.Create(FileName, fmCreate);
  168.   try
  169.     SaveToStream(Stream);
  170.   finally
  171.     Stream.Free;
  172.   end;
  173. end;
  174.  
  175. procedure TmwStringStream.SaveToStream(Stream: TStream);
  176. begin
  177.   if FSize <> 0 then Stream.WriteBuffer(Pointer(FDataString)^, FSize);
  178. end;
  179.  
  180. function TmwStringStream.Seek(Offset: Integer; Origin: Word): Longint;
  181. begin
  182.   case Origin of
  183.     soFromBeginning: FPosition := Offset;
  184.     soFromCurrent: FPosition := FPosition + Offset;
  185.     soFromEnd: FPosition := FSize - Offset;
  186.   end;
  187.   if FPosition > FSize +1 then
  188.     FPosition := FSize +1
  189.   else if FPosition < 1 then FPosition := 1;
  190.   Result := FPosition;
  191. end;
  192.  
  193. procedure TmwStringStream.SetCapacity(const NewCapacity: Integer);
  194. begin
  195.   if NewCapacity <> Capacity then
  196.   begin
  197.     SetLength(FDataString, NewCapacity);
  198.     if FSize > NewCapacity then SetSize(NewCapacity);
  199.   end;
  200. end;
  201.  
  202. procedure TmwStringStream.SetDataString(const Value: string);
  203. begin
  204.   FDataString:= Value;
  205.   FPosition:= 1;
  206.   FSize:= Length(Value);
  207. end;
  208.  
  209. procedure TmwStringStream.SetSize(NewSize: Integer);
  210. begin
  211.   fSize:= NewSize;
  212.   if Capacity < NewSize then SetCapacity(NewSize);
  213.   if FPosition > NewSize +1 then FPosition := NewSize +1;
  214. end;
  215.  
  216. function TmwStringStream.Write(const Buffer; Count: Integer): Longint;
  217. begin
  218.   Result := Count;
  219.   if FPosition + Count > Capacity then Grow(Count);
  220.   MoveNoOverlap(Buffer, Pointer(Integer(FDataString) + FPosition - 1)^, Result);
  221.   Inc(FPosition, Result);
  222.   Inc(FSize, Result);
  223. end;
  224.  
  225. procedure TmwStringStream.WriteString(const AString: string);
  226. begin
  227.   Write(Pointer(AString)^, Length(AString));
  228. end;
  229.  
  230. procedure TmwStringStream.WriteWideString(const AWideString: WideString);
  231. begin
  232.   Write(Pointer(AWideString)^, Length(AWideString)*2);
  233. end;
  234.  
  235. end.
  236.  
  237.